package com.wei.c.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewParent;
import android.webkit.WebView;

/** 带有滚动条的WebView需要禁止父组件拦截事件 **/
public class RelateNoteWebView extends WebView {
	
	private boolean needRequest;
	private boolean leftSide;
	private boolean rightSide;

	public RelateNoteWebView(Context context) {
		super(context);
	}

	public RelateNoteWebView(Context context, AttributeSet attr) {
		super(context, attr);
	}

	public RelateNoteWebView(Context context, AttributeSet attr, int defStyle) {
		super(context, attr, defStyle);
	}

	/**用来计算滚动条长度的一个参数。通过读ScrollBarDrawable类的源码得知，
	 * 滚动条的长度=getWidth()*computeHorizontalScrollExtent()/computeHorizontalScrollRange()
	 * 源码如下：
	 * 		...
	 * 
	 * 		//这里跟View类的第5678行scrollBar.setBounds(l, t, r, b)对应,后面紧接着调用scrollBar.draw(canvas)，即本段代码所在的方法
	 * 		Rect r = getBounds();

	  		int size = vertical ? r.height() : r.width();	//size 用来计算其他的参数。获取的是滚动条所在的View的宽度（横向）或高度（纵向）
            int thickness = vertical ? r.width() : r.height();	//thickness 如果是纵向滚动条则是滚动条的宽度，否则是滚动条的高度
            int length = Math.round((float) size * extent / range);	//滚动条应该显示的长度
            //
            // offset表示滚动条的左端（如果是水平的话）到本View左端的距离
            // mOffset表示当前View的content实际滚动的位置，即computeHorizontalScrollOffset()的返回值。通常情况下mScrollX的值，
            // 但是对于本组件DragReboundView却不是，因为本组件当第一个子View正好宽度全屏的时候，mScrollX并不等于0（左边有个margins作为间隙），
            // 而又必须使mOffset等于0，所以用mScrollX减去了margins。见相关实现。
            // 
            // 这里有个等量关系：
            // offset / (size - length) = mOffset / (range - extent)
            // 因而得出以下offset的计算方法。
            // 根据该等量关系，很容易理解，要想在本View的content在从最左端滚动到最右端的时候，滚动条也正好从最左端滚动到最右端，需要满足如下条件：
            // mOffset的取值范围(即computeHorizontalScrollOffset()的返回值范围)：0 <= mOffset <= (range-extent);
            //
            // 这样以来mOffset / (range - extent)的取值范围就是[0, 1], 此时offset的范围自然就是：0 <= offset <= (size - length)
            // 
            // 不这样行吗？由于我们无法重写本算法，假如content滑动到最左端时mOffset不等于0，则offset不等于0，导致滚动条不在最左端；
            // 假如content滑动到最右端时mOffset不等于range-extent，则offset不等于1，导致滚动条不在最右端。
            // 
            // 同时可以看到，length的值可以可以任意，不受影响。因为offset的值总是小于等于(size-length),总是能在mOffset/(range-extent)等于0的时候
            // 让滚动条处于最左端（offset==0），而在mOffset/(range-extent)等于1的时候让滚动条处于最右端（offset+length==size）
            // 但为了length能够反映content与本View宽度的比例，采用上面方法计算。
            // 
            // 因此我们要做的就是让computeHorizontalScrollOffset()的返回值在mOffset的范围内。
            // 
            int offset = Math.round((float) (size - length) * mOffset / (range - extent));

            // avoid the tiny thumb
            int minLength = thickness * 2;
            if (length < minLength) {
                length = minLength;
            }
            // avoid the too-big thumb
            if (offset + length > size) {
                offset = size - length;
            }

            drawThumb(canvas, r, offset, length, vertical);	//绘制滚动条
	 **/
	@Override
	protected int computeHorizontalScrollExtent() {
		return super.computeHorizontalScrollExtent();
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		boolean b = super.dispatchTouchEvent(event);
		int offset, range, extent;
		switch(event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			needRequest = true;
			b = true;
			leftSide = false;
			rightSide = false;
			
			offset = computeHorizontalScrollOffset();
			range = computeHorizontalScrollRange();
			extent = computeHorizontalScrollExtent();
			
			if(offset>0 && offset<range-extent) {
				ViewParent p = getParent();
				if(p != null) p.requestDisallowInterceptTouchEvent(true);
				needRequest = false;
				b = true;
			}else {
				if(offset <= 0) {
					leftSide = true;
				}else if(offset >= range-extent) {
					rightSide = true;
				}
			}
			break;
		case MotionEvent.ACTION_MOVE:
			if(needRequest) {
				offset = computeHorizontalScrollOffset();
				range = computeHorizontalScrollRange();
				extent = computeHorizontalScrollExtent();
				if(offset>0 && offset<range-extent) {
					ViewParent p = getParent();
					if(p != null) p.requestDisallowInterceptTouchEvent(true);
					needRequest = false;
					b = true;
				}else {
					if(offset <= 0) {
						leftSide = true;
					}else if(offset >= range-extent) {
						rightSide = true;
					}
					if(leftSide && rightSide) {
						ViewParent p = getParent();
						if(p != null) p.requestDisallowInterceptTouchEvent(true);
						needRequest = false;
						b = true;
					}
				}
			}
			break;
		}
		return b;
	}

    /*private boolean mDisallowInterceptRequested, mNeedRequest;
    private boolean leftSide, rightSide, topSide, bottomSide;

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        boolean consume = super.dispatchTouchEvent(event);
        int offsetH, rangeH, extentH;
        int offsetV, rangeV, extentV;
        switch(event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (AppConfig.DEBUG) Log.i("MyWebView", "ACTION_DOWN");
            mDisallowInterceptRequested = false;
            mNeedRequest = false;
            consume = true;

            leftSide = rightSide = false;
            offsetH = computeHorizontalScrollOffset();
            rangeH = computeHorizontalScrollRange();
            extentH = computeHorizontalScrollExtent();
            if (offsetH > 0 && offsetH < rangeH - extentH) {
                requestDisallowIntercept();
                mNeedRequest = false; 
                consume = true;
            } else {
                if (offsetH <= 0) leftSide = true;
                if (offsetH >= rangeH - extentH) rightSide = true;
                if (leftSide && rightSide) {
                    mNeedRequest = false;
                } else {
                    mNeedRequest = leftSide || rightSide;
                }
            }
            if (AppConfig.DEBUG) Log.i("MyWebView", "leftSide:" + leftSide + ", rightSide:" + rightSide);

            if (!mDisallowInterceptRequested) {
                topSide = bottomSide = false;
                offsetV = computeVerticalScrollOffset();
                rangeV = computeVerticalScrollRange();
                extentV = computeVerticalScrollExtent();
                if (offsetV > 0 && offsetV < rangeV - extentV) {
                    requestDisallowIntercept();
                    mNeedRequest = false; 
                    consume = true;
                } else {
                    if (offsetV <= 0) topSide = true;
                    if (offsetV >= rangeV - extentV) bottomSide = true;
                    if (topSide && bottomSide) {
                        mNeedRequest |= false;  //注意是|=
                    } else {
                        mNeedRequest |= topSide || bottomSide;  //注意是|=
                    }
                }
                if (AppConfig.DEBUG) Log.i("MyWebView", "topSide:" + topSide + ", bottomSide:" + bottomSide);
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (AppConfig.DEBUG) Log.d("MyWebView", "ACTION_MOVE");
            if (mNeedRequest) {
                offsetH = computeHorizontalScrollOffset();
                rangeH = computeHorizontalScrollRange();
                extentH = computeHorizontalScrollExtent();
                if (offsetH > 0 && offsetH < rangeH - extentH
                        ||!leftSide && rightSide && offsetH <= 0
                        || leftSide && !rightSide && offsetH >= rangeH - extentH) {
                    requestDisallowIntercept();
                    mNeedRequest = false;
                    consume = true;
                }
                if (AppConfig.DEBUG) Log.d("MyWebView", "leftSide:" + leftSide + ", rightSide:" + rightSide);
                if (mNeedRequest) {
                    offsetV = computeVerticalScrollOffset();
                    rangeV = computeVerticalScrollRange();
                    extentV = computeVerticalScrollExtent();
                    if (offsetV > 0 && offsetV < rangeV - extentV
                            ||!topSide && bottomSide && offsetV <= 0
                            || topSide && !bottomSide && offsetV >= rangeV - extentV) {
                        requestDisallowIntercept();
                        mNeedRequest = false;
                        consume = true;
                    }
                    if (AppConfig.DEBUG) Log.d("MyWebView", "topSide:" + topSide + ", bottomSide:" + bottomSide);
                }
            }
            break;
        }
        return consume;
    }

    private void requestDisallowIntercept() {
        if(!mDisallowInterceptRequested) {
            final ViewParent parent = getParent();
            if(parent != null) parent.requestDisallowInterceptTouchEvent(true);
            mDisallowInterceptRequested = true;
        }
    }*/
}
